#include <tshark_manager.h>
#include <miscutil.hpp>
#include <translateUtil.h>
#include <json/json.h>
#include <loguru.hpp>
#include <filesystem>
#include <sstream>
#include <functional>
#include <set>
#include <iostream>

namespace Tshark
{
    TsharkManager::TsharkManager(const std::string &workDir, const std::string &editcapPath)
    {
        this->tsharkPath = "tshark";
        this->workDir = workDir;
        this->editcapPath = editcapPath;
        this->storage = std::make_shared<TsharkDataBase>();
    }

    TsharkManager::~TsharkManager()
    {
    }

    bool TsharkManager::startCapture(const std::string &adapterName)
    {
        reset();
        // // 打开数据库并创建t_packets表
        // this->storage->openDataBase(dbName);
        std::unique_lock<std::mutex> lock(this->captureLock);
        this->stopFlag = false;
        lock.unlock();
        // 开启捕获线程
        this->captureWorkThread = std::make_shared<std::thread>(&TsharkManager::captureWorkThreadEntry, this, adapterName);
        // 开启存储线程
        this->storageThread = std::make_shared<std::thread>(&TsharkManager::storageThreadEntry, this);
        return true;
    }

    bool TsharkManager::stopCapture()
    {
        std::unique_lock<std::mutex> lock(this->captureLock);
        this->stopFlag = true;
        lock.unlock();
        if (!Util::ProcessUtil::killAllDescendantsProcess(this->captureTsharkPid, true)) // 成功返回 0
        {
#if defined __unix__ || defined __APPLE__
            int status;
            PID_T pid;
            std::string msg;
            while ((pid = waitpid(this->captureTsharkPid, &status, WNOHANG | WUNTRACED)) >= 0)
            {
                if (pid == 0)
                {
                    continue;
                }
                if (WIFEXITED(status)) // 子进程正常退出
                {
                    msg = fmt::format("exit with status: {}", WEXITSTATUS(status));
                }
                if (WIFSIGNALED(status)) // 子进程由信号终止
                {
                    msg = fmt::format("terminate by signum: {}", WTERMSIG(status));
                }
                if (WIFSTOPPED(status)) // 子进程由信号停止
                {
                    msg = fmt::format("stop by signum: {}", WSTOPSIG(status));
                }
                LOG_F(WARNING, "child process pid:%d with exit: %s\n", pid, msg.c_str());
            }
#elif _WIN32
#endif
        }
        else
        {
            LOG_F(ERROR, "kill child process %d error\n", this->captureTsharkPid);
        }
        // join捕获线程
        this->captureWorkThread->join();
        this->captureWorkThread.reset();
        // join存储线程
        this->storageThread->join();
        this->storageThread.reset();
        return true;
    }

    error_code TsharkManager::analysisFile(const std::string &filePath)
    {
        reset();
        currFilePath = Util::MiscUtil::getPcapNameByCurrentTimestamp(true);
        if (!this->convertToPcap(filePath, currFilePath))
        {
            LOG_F(ERROR, "convert to pcap failed");
            return error_code::parse_pcap_failed;
        }
        error_code ec{error_code::success};
        if (!std::filesystem::exists(filePath))
        {
            ec = error_code::file_not_exits;
            return ec;
        }
        // currFilePath = filePath;
        std::vector<std::string> tsharkArgs = {
            tsharkPath,
            "-r",
            filePath,
            "-T",
            "fields",
            "-e",
            "frame.number",
            "-e",
            "frame.time_epoch",
            "-e",
            "frame.cap_len",
            "-e",
            "ip.src",
            "-e",
            "ipv6.src",
            "-e",
            "ip.dst",
            "-e",
            "ipv6.dst",
            "-e",
            "tcp.srcport",
            "-e",
            "udp.srcport",
            "-e",
            "tcp.dstport",
            "-e",
            "udp.dstport",
            "-e",
            "_ws.col.Protocol",
            "-e",
            "_ws.col.Info",
            "-e",
            "frame.len",
            "-e",
            "eth.src",
            "-e",
            "eth.dst",
        };

        std::string cmd;
        for (auto &arg : tsharkArgs)
        {
            cmd += arg + " ";
        }
        FILE *pipe = popen(cmd.c_str(), "r");
        if (!pipe)
        {
            ec = error_code::file_open_failed;
            return ec;
        }
        // 创建存储数据库线程
        this->stopFlag = false;
        this->storageThread = std::make_shared<std::thread>([&]()
                                                            { this->storageThreadEntry(); });
        std::size_t file_offset = sizeof(DataType::PcapHeader); // 获取数据包在PCap文件中的偏移量
        char buffer[4096];
        while (fgets(buffer, 4096, pipe))
        {
            Result<DataType::Packet> packResult = this->parseLine(buffer);
            if (packResult)
            {
                packResult.result.file_offset = file_offset;
                processPacket(std::make_shared<DataType::Packet>(packResult.result));
                // this->allPackets.emplace(packResult.result.frame_number, std::make_shared<DataType::Packet>(packResult.result));
                // {
                //     std::lock_guard<std::mutex> lock(this->storageLock);
                //     this->packetsTobeStore.emplace_back(std::make_shared<DataType::Packet>(packResult.result));
                // }
                file_offset += sizeof(DataType::PacketHeader) + packResult.result.cap_len;
            }
            else
            {
                ec = error_code::parse_error;
#ifdef _DEBUG
                std::cerr << buffer << " parse error!" << std::endl;
                std::cin.get();
#endif
            }
        }
        pclose(pipe);
        // 等待存储进程结束
        this->stopFlag = true;
        this->storageThread->join();
        this->storageThread.reset();
        return ec;
    }

    void TsharkManager::printAllPackets()
    {
        for (auto &packPtr : this->allPackets)
        {
            LOG_F(INFO, "%s", fmt::format("{}\n", packPtr.second->to_string()).c_str());
        }
    }

    Result<std::vector<unsigned char>> TsharkManager::getPacketHexData(std::uint32_t framNum)
    {
        Result<std::vector<unsigned char>> hexResult;
        hexResult.ec = error_code::success;
        // 查找是否存在该framNum
        auto packetPair = this->allPackets.find(framNum);
        if (packetPair == this->allPackets.end())
        {
            hexResult.ec = error_code::out_of_range;
            hexResult.ec;
        }
        // 打开pcap文件
        std::ifstream pcapFile(currFilePath, std::ios::binary);
        if (!pcapFile.is_open())
        {
            hexResult.ec = error_code::file_open_failed;
            return hexResult;
        }
        // 获取文件偏移后复制到result中，文件偏移在analysisFile时得到
        std::size_t file_offset = allPackets[framNum]->file_offset;
        pcapFile.seekg(file_offset + sizeof(DataType::PacketHeader), std::ios::beg); // 设置文件偏移为 begin+包头部(即从包的有效数据部分开始读取)
        hexResult.result.resize(packetPair->second->cap_len);
        pcapFile.read(reinterpret_cast<char *>(hexResult.result.data()), packetPair->second->cap_len);
        pcapFile.close();
        return hexResult;
    }

    Result<std::vector<DataType::AdapterInfo>> TsharkManager::getNetworkAdapter()
    {
        // 需要过滤掉的虚拟网卡
        std::set<std::string> specialInterfaces = {"sshdump", "ciscodump", "udpdump", "randpkt"};
        Result<std::vector<DataType::AdapterInfo>> adaptersRes;
        std::string cmd = fmt::format("{} -D", this->tsharkPath);
        // FILE *pipe = popen(cmd.c_str(), "r"); // note: 使用 std::unique_ptr来实现自动调用pclose
        std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
        if (!pipe)
        {
            adaptersRes.ec = error_code::popen_failed;
            return adaptersRes;
        }
        char buffer[256];
        std::string adaptersStr;
        while (fgets(buffer, 256, pipe.get()))
        {
            adaptersStr += buffer;
        }
        std::stringstream ss(adaptersStr);
        std::string line;
        // "1. ens33\n
        // 2. any\n
        // 3. lo (Loopback)\n
        // 4. ens38\n
        // 5. nflog\n
        // 6. nfqueue\n
        // 7. usbmon1\n
        // 8. usbmon2\n
        // 9. ciscodump (Cisco remote capture)\n
        // 10. randpkt (Random packet generator)\n
        // 11. sshdump (SSH remote capture)\n
        // 12. udpdump (UDP Listener remote capture)\n"
        while (std::getline(ss, line))
        {
            // id
            int start = 0, end = 0;
            end = line.find('.', start);
            if (end == std::string::npos)
            {
                continue;
            }
            int id = std::stoi(line.substr(start, end - start));
            // name
            start = line.find(' ', end);
            if (start == std::string::npos)
            {
                continue;
            }
            start += 1;
            end = line.find(' ', start);
            if (end == std::string::npos)
            {
                end = line.size();
            }
            std::string name = line.substr(start, end - start);
            // 处理特殊网卡
            if (specialInterfaces.find(name) != specialInterfaces.end())
            {
                LOG_F(WARNING, "special network interface: %s\n", name.c_str());
                continue;
            }
            // remark
            start = line.find('(', start);
            end = line.rfind(')');
            std::string remark = "";
            if (start != std::string::npos && end != std::string::npos && end > start)
            {
                start += 1;
                remark = line.substr(start, end - start);
            }
            DataType::AdapterInfo adapter(id, name, remark);
            adaptersRes.result.emplace_back(adapter);
        }

        // pclose(pipe);
        adaptersRes.ec = error_code::success;
        return adaptersRes;
    }

    void TsharkManager::startMonitorAdaptersFlowTrend()
    {
        reset();
        std::lock_guard<std::recursive_mutex> lock(this->adapterFlowTrendMapLock);
        this->adapterFlowTrendMonitorStartTime = time(nullptr);
        // 1、获取网卡
        auto getAdaptersRes = getNetworkAdapter();
        std::vector<DataType::AdapterInfo> adapters;
        if (!getAdaptersRes)
        {
            LOG_F(ERROR, "get adapters failed!");
            return;
        }
        adapters = getAdaptersRes.result;

        // 2、为每个网卡创建一个monitorInfo
        for (auto &adapter : adapters)
        {
            this->adapterFlowTrendMonitorMap.insert(std::make_pair<>(adapter.name, DataType::AdapterMonitorInfo()));
            auto &monitorInfo = this->adapterFlowTrendMonitorMap[adapter.name];
            monitorInfo.monitorThread = std::make_shared<std::thread>(&TsharkManager::adpterFlowTrendMonitorThreadEntry, this, adapter.name);
            if (monitorInfo.monitorThread == nullptr)
            {
                LOG_F(ERROR, "监控线程创建失败，网卡名：%s", adapter.name.c_str());
            }
            else
            {
                LOG_F(INFO, "监控线程创建成功，网卡名：%s，monitorThread: %p", adapter.name.c_str(), monitorInfo.monitorThread.get());
            }
        }
#ifdef _WIN32
        Util::ProcessUtil::printProcessTree(GetCurrentProcessId(), false);
#else
        Util::ProcessUtil::printProcessTree(getpid(), false);
#endif
    }

    void TsharkManager::stopMonitorAdaptersFlowTrend()
    {
        std::unique_lock<std::recursive_mutex> lock(this->adapterFlowTrendMapLock);
        for (auto &monitorInfoPair : this->adapterFlowTrendMonitorMap)
        {
            // 杀死子进程
            Util::ProcessUtil::killAllDescendantsProcess(monitorInfoPair.second.tstarkPid, true);
            // 关闭 monitorInfo 的管道
            pclose(monitorInfoPair.second.monitorTsharkPipe);
            // join monitorInfo 的子线程
            if (monitorInfoPair.second.monitorThread && monitorInfoPair.second.monitorThread->joinable())
            {
                monitorInfoPair.second.monitorThread->join();
                monitorInfoPair.second.monitorThread.reset();
            }
            LOG_F(INFO, "监控线程退出成功，网卡名：%s，monitorThread: %p", monitorInfoPair.first.c_str(), monitorInfoPair.second.monitorThread.get());
        }
        // this->adapterFlowTrendMonitorMap.clear();
    }

    bool TsharkManager::convertToPcap(const std::string &inputFile, const std::string &outputFile)
    {
        // 构造 editcap 命令,将pcapng转换为pcap格式
        std::string command = editcapPath + " -F pcap " + inputFile + " " + outputFile;
        if (!Util::ProcessUtil::Exec(command))
        {
            LOG_F(ERROR, "failed to convert to pcap format, command: %s", command.c_str());
            return false;
        }
        LOG_F(INFO, "successfully converted %s to %s in pcap format", inputFile.c_str(), outputFile.c_str());
        return true;
    }

    Result<DataType::Packet> TsharkManager::parseLine(std::string line)
    {
        if (!line.empty() && line.back() == '\n')
        {
            line.pop_back();
        }
        Result<DataType::Packet> packRes;
        packRes.ec = error_code::parse_error;
        auto res = packRes.result.parseLine(line);
        if (res)
        {
            packRes.ec = error_code::success;
        }
        else
        {
#ifdef _DEBUG
            std::cin.get();
#endif
        }

        return packRes;
    }

    void TsharkManager::captureWorkThreadEntry(const std::string &adapterName)
    {
        std::string pcapfile = "./resource/capture.pcap";
        std::vector<std::string> tsharkArgs = {
            tsharkPath,
            "-i",
            adapterName,
            "-w",
            pcapfile,
            "-F",
            "pcap",
            "-T",
            "fields",
            "-e",
            "frame.number",
            "-e",
            "frame.time_epoch",
            "-e",
            "frame.cap_len",
            "-e",
            "ip.src",
            "-e",
            "ipv6.src",
            "-e",
            "ip.dst",
            "-e",
            "ipv6.dst",
            "-e",
            "tcp.srcport",
            "-e",
            "udp.srcport",
            "-e",
            "tcp.dstport",
            "-e",
            "udp.dstport",
            "-e",
            "_ws.col.Protocol",
            "-e",
            "_ws.col.Info",
            "-e",
            "frame.len",
            "-e",
            "eth.src",
            "-e",
            "eth.dst",
        };

        std::string cmd;
        for (auto &arg : tsharkArgs)
        {
            cmd += arg + " ";
        }
        /*
        note:
            decltype(&pclose)> : 是 int (*)(FILE*) ，即一个指向函数的指针。
            decltype(pclose)> : 是 int (FILE*) ，即表示一个函数类型。
        C++标准库要求std::unique_ptr的删除器必须是一个可调用对象（如函数指针、lambda表达式、函数对象等），
        而不能是函数类型本身，所以这里需要使用&pclose。

        两种方法：推荐第二种方法，更灵活
            std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
            std::unique_ptr<FILE, std::function<void(FILE *)>> pipe(popen(cmd.c_str(), "r"),
                                                                [](FILE *pipe)
                                                                { pclose(pipe); });

        */
        // std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
        std::unique_ptr<FILE, std::function<void(FILE *)>> pipe(Util::ProcessUtil::PopenEX(cmd, &this->captureTsharkPid), [](FILE *pipe)
                                                                { pclose(pipe); });
        if (!pipe)
        {
            LOG_F(ERROR, "PopenEX error\n");
            return;
        }
        char buffer[4096];
        std::size_t file_offset = sizeof(DataType::PcapHeader); // 获取数据包在PCap文件中的偏移量
        while (fgets(buffer, 4096, pipe.get()) && !this->stopFlag)
        {
            std::string line = buffer;
            // 过滤特殊行
            if (line.find("Running") != std::string::npos || line.find("Capturing on") != std::string::npos || line == "\n")
            {
                LOG_F(WARNING, "capture message: %s\n", line.c_str());
                continue;
            }
            std::shared_ptr<DataType::Packet> packPtr = std::make_shared<DataType::Packet>();
            DataType::ParseResult parseRes = packPtr->parseLine(line);
            if (parseRes)
            {
                LOG_F(INFO, "%s\n", line.c_str());
                packPtr->file_offset = file_offset + sizeof(DataType::PacketHeader);
                this->processPacket(packPtr);
                file_offset += sizeof(DataType::PacketHeader) + packPtr->cap_len;
            }
            else
            {
                LOG_F(ERROR, "parse error: %s\n", line.c_str());
            }
        }
        // 记录文件路径
        currFilePath = pcapfile;
    }

    void TsharkManager::adpterFlowTrendMonitorThreadEntry(const std::string &adapterName)
    {
        this->adapterFlowTrendMapLock.lock();
        // find线程不安全
        if (this->adapterFlowTrendMonitorMap.find(adapterName) == this->adapterFlowTrendMonitorMap.end())
        {
            LOG_F(WARNING, "can't find adapter: %s\n", adapterName.c_str());
            return;
        }
        char buffer[256] = {0};
        std::map<long, long> &trafficPerSecond = this->adapterFlowTrendMonitorMap[adapterName].flowTrendData;

        // tshark命令,指定网卡,实时捕获时间戳和数据包长度
        std::string tsharkCmd = fmt::format("{} -i \"{}\" -T fields -e frame.time_epoch -e frame.len", tsharkPath, adapterName);
        LOG_F(INFO, "启动网卡流量监控: %s", tsharkCmd.c_str());
        PID_T tsharkPid = 0;
        FILE *tsharkPipe = Util::ProcessUtil::PopenEX(tsharkCmd, &tsharkPid);
        if (!tsharkPipe)
        {
            throw std::runtime_error("Failed to run tshark command.");
            // return;
        }

        // 保存管道
        // 修改 adapterFlowTrendMonitorMap 数据需要加锁
        adapterFlowTrendMonitorMap[adapterName].monitorTsharkPipe = tsharkPipe;
        adapterFlowTrendMonitorMap[adapterName].tstarkPid = tsharkPid;
        adapterFlowTrendMonitorMap[adapterName].adapterName = adapterName;
        this->adapterFlowTrendMapLock.unlock();
        // 打印进程信息
        std::string processInfo = Util::ProcessUtil::printProcessTree(tsharkPid, true);
        LOG_F(INFO, "print process: %d info:", tsharkPid);
        LOG_F(INFO, "%s", processInfo.c_str());

        while (fgets(buffer, sizeof(buffer), tsharkPipe))
        {
            /*
            note: 将用'\t'、' '等字符连接起来的一行字符串，split到多个不同变量的比较优雅的方式
            1、使用istringstream、stringstream进行分割
            2、手动使用std::string::find()、find_first_of等函数实现一个split函数
            */
            std::string line = buffer;
            std::istringstream iss(line);
            std::string timestampStr, lenStr;
            if (line.find("capturing") != std::string::npos || line.find("Capturing") != std::string::npos || line.find("Runing as user") != std::string::npos)
            {
                continue;
            }
            if (!(iss >> timestampStr >> lenStr))
            {
                continue;
            }
            long timestamp = static_cast<long>(std::atof(timestampStr.c_str())); // 仅保留秒数部分
            long len = std::atol(lenStr.c_str());
            if (timestamp == 0 || len == 0)
            {
                LOG_F(WARNING, "get timestamp or length failed: %s", line.c_str());
                continue;
            }
            trafficPerSecond[timestamp] += len;
            while (trafficPerSecond.size() > 300)
            {
                auto it = trafficPerSecond.begin();
                LOG_F(INFO, "Removing old data for second: %ld, Traffic: %ld bytes", it->first, it->second);
                trafficPerSecond.erase(it);
            }
        }
        LOG_F(INFO, "%s: adapterFlowTrendMonitorThreadEntry 已结束", adapterName.c_str());
    }

    void TsharkManager::storageThreadEntry()
    {
        while (!this->stopFlag)
        {
            /*
            note: this->storageLock 需要在 sleep_for 之前解锁，否则另外一个线程可能一直获取不到锁
            比如：
                whlie(...){
                    std::lock_guard<std::mutex> lock(this->packetsTobeStore);
                    this->storage->storePackets(this->packetsTobeStore);
                    this->packetsTobeStore.clear();
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                }
                sleep_for 相当于没有用了
            */
            this->storageLock.lock();
            this->storage->storePackets(this->packetsTobeStore);
            this->packetsTobeStore.clear();
            this->storageLock.unlock();
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
        // 结束之后等待一会，插入剩余的packets
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        std::lock_guard<std::mutex> lock(this->storageLock);
        this->storage->storePackets(this->packetsTobeStore);
        this->packetsTobeStore.clear();
    }

    void TsharkManager::processPacket(std::shared_ptr<DataType::Packet> packet)
    {
        this->allPackets.emplace(std::make_pair<>(packet->frame_number, packet));
        {
            std::lock_guard<std::mutex> lock(this->storageLock);
            this->packetsTobeStore.emplace_back(packet);
        }
    }

    void TsharkManager::reset()
    {
        LOG_F(INFO, "reset called!");

        // 停止之前的操作
        if (m_workStatus == WorkStatus::STATUS_CAPTURING)
        {
            this->stopCapture();
        }
        if (m_workStatus == WorkStatus::STATUS_MONITORING)
        {
            this->stopMonitorAdaptersFlowTrend();
        }

        this->captureTsharkPid = 0;
        this->m_workStatus = WorkStatus::STATUS_IDLE;

        // join captrue线程
        this->stopFlag = true;
        if (this->captureWorkThread && this->captureWorkThread->joinable())
        {
            this->captureWorkThread->join();
            this->captureWorkThread.reset();
        }

        // join storage线程
        if (this->storageThread && this->storageThread->joinable())
        {
            this->storageThread->join();
            this->storageThread.reset();
        }

        // 清空数据
        this->packetsTobeStore.clear();
        this->allPackets.clear();
        remove(currFilePath.c_str());
        currFilePath = "";
        // 重置数据库,删除之前的db文件并重新创建
        this->storage.reset();
        std::string dbFullPath = fmt::format("{}/{}", this->workDir, "packets.db");
        remove(dbFullPath.c_str());
        this->storage = std::make_shared<TsharkDataBase>();
        this->storage->openDataBase(dbFullPath);
    }

    void TsharkManager::getAdapterFlowTrendData(std::map<std::string, std::map<long, long>> &flowTrendData)
    {
        long timeNow = time(nullptr);
        // 数据从最左边冒出来
        // 一开始：以最开始监控时间为左起点，终点为未来300秒
        // 随着时间推移，数据逐渐填充完这300秒
        // 超过300秒之后，结束节点就是当前，开始节点就是当前-300
        long startWindow = timeNow - this->adapterFlowTrendMonitorStartTime <= 300 ? this->adapterFlowTrendMonitorStartTime : timeNow - 300;
        long endWindow = timeNow - this->adapterFlowTrendMonitorStartTime <= 300 ? adapterFlowTrendMonitorStartTime + 300 : timeNow;
        std::lock_guard<std::recursive_mutex> lock(this->adapterFlowTrendMapLock);
        for (auto &flowTrendMonitorPair : this->adapterFlowTrendMonitorMap)
        {
            flowTrendData.insert(std::make_pair<>(flowTrendMonitorPair.first, std::map<long, long>()));
            for (auto time = startWindow; time < endWindow; ++time)
            {
                // 如果trafficPerSecond中存在该时间戳，则使用已有数据；否则填充为0
                if (flowTrendMonitorPair.second.flowTrendData.find(time) != flowTrendMonitorPair.second.flowTrendData.end())
                {
                    flowTrendData[flowTrendMonitorPair.first][time] = flowTrendMonitorPair.second.flowTrendData[time];
                }
                else
                {
                    flowTrendData[flowTrendMonitorPair.first][time] = 0;
                }
            }
        }
    }

    bool TsharkManager::getPacketDetailInfo(uint32_t frameNumber, std::string &result)
    {
        // 以下两条指令生成协议的xml树
        // editcap -r ./resource/packets.pcap 5-10.pcap 5-10 // 将packet.pcap的frame.number5-10放到./resource/packets.pcap中
        // tshark -r 5.pcap -T pdml > protocol_tree.xml // 将5.pcap转换为xml的格式
        std::string tmpFileName = Util::MiscUtil::getRandomString(10) + ".pcap";
        std::string editCapCmd = fmt::format("{} -r {} {} {}-{}",
                                             this->editcapPath, this->currFilePath, tmpFileName, frameNumber, frameNumber);
        LOG_F(INFO, "exec command: %s", editCapCmd.c_str());
        if (!Util::ProcessUtil::Exec(editCapCmd))
        {
            LOG_F(ERROR, "%s exec failed!", editCapCmd.c_str());
            return false;
        }
        std::string tsharkCmd = fmt::format("{} -r {} -T pdml", this->tsharkPath, tmpFileName);
        pid_t outPid;
        LOG_F(INFO, "exec command: %s", tsharkCmd.c_str());
        std::unique_ptr<FILE, decltype(&pclose)> pipe(Util::ProcessUtil::PopenEX(tsharkCmd, &outPid), pclose);
        if (!pipe)
        {
            std::remove(tmpFileName.c_str());
            LOG_F(ERROR, "%s PopenEX failed!", tsharkCmd.c_str());
            return false;
        }

        char buffer[4096];
        memset(buffer, 0, sizeof(buffer));
        // note: 给FILE设置缓冲区,NULL表示系统分配缓冲区,_IOFBF表示按文件缓冲
        std::setvbuf(pipe.get(), NULL, _IOFBF, sizeof(buffer));
        std::string xmlContent = "";
        while (fgets(buffer, sizeof(buffer) - 1, pipe.get()))
        {
            xmlContent += buffer;
            memset(buffer, 0, sizeof(buffer));
        }
        std::remove(tmpFileName.c_str());

        // 将xml转换为json
        Json::Value jsonVal;
        if (!Util::MiscUtil::xml2Json(xmlContent, jsonVal))
        {
            return false;
        }
        Util::TranslateUtil::translateShowNameFields(jsonVal);
        Json::StreamWriterBuilder builder;
        // builder["emitUTF8"] = true; // 指定jsoncpp中文编码，这里直接修改了jsoncpp的源码，所以不用设置了
        result = Json::writeString(builder, jsonVal);

#if 0 // 将 Json::Value 转换为文件
        std::ofstream ofs("./resource/test.json");
        if (!ofs.is_open())
        {
            return 0;
        }
        const std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
        writer->write(jsonVal, &ofs);
#endif
        return true;
    }

    bool TsharkManager::queryPackets(const std::string &ip, uint16_t port, std::vector<std::shared_ptr<DataType::Packet>> &packets)
    {
        return this->storage->queryPackets(ip, port, packets);
    }

    bool TsharkManager::queryPackets(const QueryConditon &condition, std::vector<std::shared_ptr<DataType::Packet>> &packets)
    {
        return this->storage->queryPackets(condition, packets);
    }

}
